package com.sensetime.bi.senselink.server.rtsp.client;


import com.sensetime.bi.senselink.server.handler.ForwardMsgToPlayerHandler;
import com.sensetime.bi.senselink.server.handler.ForwardRTPToPlayerHandler;
import com.sensetime.bi.senselink.server.parse.PackageDecoder;
import com.sensetime.bi.senselink.server.parse.RtpEncoder;
import io.netty.bootstrap.Bootstrap;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.InputStreamReader;

/**
 * 多连接客户端
 */
@Slf4j
public class RtspClient {
    private static RtspClient instance = new RtspClient();

    /**服务类*/
    private Bootstrap bootstrap = new Bootstrap();

    private RtspClient() { init();}

    public static RtspClient getInstance() {
        return instance;
    }

    /**初始化*/
    public void init(){
        //worker
        EventLoopGroup worker = new NioEventLoopGroup();

        //设置工作线程
        this.bootstrap.group(worker);

        //初始化channel
        bootstrap.channel(NioSocketChannel.class);
        bootstrap.option(ChannelOption.TCP_NODELAY, true);
        bootstrap.option(ChannelOption.RCVBUF_ALLOCATOR, new FixedRecvByteBufAllocator(131070));

        //设置handler管道
        bootstrap.handler(new ChannelInitializer<Channel>() {
            @Override
            protected void initChannel(Channel channel) throws Exception {
                channel.pipeline().addLast("RawPackagedecoder", new PackageDecoder());
                channel.pipeline().addLast(new ForwardMsgToPlayerHandler());
                channel.pipeline().addLast(new ForwardRTPToPlayerHandler());
                channel.pipeline().addLast(new StringEncoder(CharsetUtil.UTF_8));
                channel.pipeline().addLast(new RtpEncoder());
            }
        });

    }

    public Channel connect(String ip, Integer port) {
        ChannelFuture channelFuture = null;
        try {
            channelFuture = bootstrap.connect(ip, port).sync();
        } catch (InterruptedException e) {
            log.error("Cannot connect to [" + ip + ":" + port + "], errorMsg:" + e.getMessage());
            e.printStackTrace();
            return null;
        }
        return channelFuture.channel();
    }

    public static void main(String[] args) {
        RtspClient instance = RtspClient.getInstance();
//        Channel channel = instance.connect("10.4.10.135", 9554);
        Channel channel = instance.connect("10.4.189.70", 554);
        String optionRequest = "OPTIONS rtsp://10.4.189.70:554 RTSP/1.0\r\n" +
                "CSeq: 1\r\n" +                "\r\n";
        channel.writeAndFlush(optionRequest);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));
        while(true){
            try {
                System.out.println("请输入:");
                String msg = bufferedReader.readLine();
                channel.writeAndFlush(msg+"\r\n");
//                channel.close();
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
//        log.info("====================");
    }

//    /**重连*/
//    private void reconect(Channel channel) {
//        //此处可改为原子操作
//        synchronized(channel){
//            if(channels.indexOf(channel) == -1){
//                return ;
//            }
//
//            Channel newChannel = bootstrap.connect("0.0.0.0", 9099).channel();
//            channels.set(channels.indexOf(channel), newChannel);
//
//            System.out.println(channels.indexOf(channel) + "位置的channel成功进行重连!");
//        }
//    }

}